#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from my_utils import logging_config
logger = logging_config.init_logger()


import numpy as np
import pandas as pd
import copy

def preprocess(data, need_standard=False):
    for ip in data:
        # 获取类似于原来的二维表，一个ip对应一个表，每一行对应一个时间上的所有指标值（时间是相对的不是绝对的）
        raw_data = np.asarray(copy.deepcopy(data[ip]['raw'])).T

        missing_flag_table = data[ip]['missing_flag']  # 引用传递
        outlier_flag_table = data[ip]['outlier_flag']  # 引用传递

        new_data = preprocess_one_table(raw_data, missing_flag_table, outlier_flag_table, need_standard)
        new_data = new_data.T  # 再转置回来，一行是一个metric的所有值（按时间序列）

        data[ip]['preprocessed'] = new_data


    restore_data_after_preprocess = []
    for ip in data:
        for i in range(len(data[ip]['preprocessed'])):
            row = data[ip]['preprocessed'][i]
            for j, value in enumerate(row):
                if data[ip]['complete_flag'][i][j] == True:
                    # 删去填充值
                    pass
                else:
                    ts = data[ip]['raw-ts'][i][j]
                    restore_data_after_preprocess.append(
                        f"{data[ip]['cols'][i]}:{ip.split('_')[0]}:{ts}:{value}|{ts}"
                    )
    return restore_data_after_preprocess, data

def preprocess_one_table(temp_arr, missing_flag_table, outlier_flag_table, need_standard):
    """
    missing_flag_table, outlier_flag_table 是未转置的flag表，所以需要注意行号和列号的设置
    """
    col_num = temp_arr.shape[1]
    row_num = temp_arr.shape[0]
    for col_index in range(0, col_num):
        value = temp_arr[:, col_index]
        missing_flag_col = missing_flag_table[col_index]
        outlier_flag_col = outlier_flag_table[col_index]
        np_array = preprocess_one_col(value, row_num, missing_flag_col, outlier_flag_col, need_standard)

        temp_arr[:, col_index] = np_array
    return temp_arr

def standardization(data_col):
    # min-max标准化，是对原始数据的线性变换，使结果值映射到[0 - 1]之间
    gap = max(data_col) - min(data_col)
    gap = gap if not gap == 0 else 1
    data_col = [(x - min(data_col)) / gap for x in data_col]
    return data_col


def preprocess_one_col(data_col, row_num, missing_flag_col, outlier_flag_col, need_standard):
    """
    data_col: 一列数据
    """

    # missingValue=pd.notna(data_col)
    # print(missingValue)

    # 存在缺失值，进行缺失值填充
    missing_value_num = pd.isna(data_col).sum()
    if missing_value_num > 0:
        # 进行缺失值填充
        for item_index, item in enumerate(data_col):
            if np.isnan(item):
                data_col[item_index] = 0.0
                missing_flag_col[item_index] = True

        # data_col[np.isnan(data_col)] = 0.0

    # 百分比离群点检测
    data_col = percent_range(data_col, row_num, outlier_flag_col, 0.025, 0.975)
    if need_standard == True:
        data_col = standardization(data_col)
    return data_col


# 百分位法:原始参数 min=0.025， max=0.975
def percent_range(data_col, row_num, outlier_flag_col, min=0.20, max=0.80):
    range_max = np.percentile(data_col, max * 100)
    range_min = -np.percentile(-data_col, (1 - min) * 100)

    result = np.empty((row_num,))

    for i, value in enumerate(data_col):
        if range_max >= value >= range_min:
            result[i] = data_col[i]
        else:
            result[i] = (range_max + range_min) / 2
            outlier_flag_col[i] = True
    return result
